{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a3e3ebc4-57af-4fe4-bdd3-36aff67bf276",
   "metadata": {},
   "source": [
    "## Hierarchical Agent Teams\n",
    "\n",
    "In our previous example ([Agent Supervisor](./agent_supervisor.ipynb)), we introduced the concept of a single supervisor node to route work between different worker nodes.\n",
    "\n",
    "But what if the job for a single worker becomes too complex? What if the number of workers becomes too large?\n",
    "\n",
    "For some applications, the system may be more effective if work is distributed _hierarchically_.\n",
    "\n",
    "You can do this by composing different subgraphs and creating a top-level supervisor, along with mid-level supervisors.\n",
    "\n",
    "To do this, let's build a simple research assistant! The graph will look something like the following:\n",
    "\n",
    "![diagram](./img/hierarchical-diagram.png)\n",
    "\n",
    "This notebook is inspired by the paper [AutoGen: Enabling Next-Gen LLM Applications via Multi-Agent Conversation](https://arxiv.org/abs/2308.08155), by Wu, et. al. In the rest of this notebook, you will:\n",
    "\n",
    "1. Define the agents' tools to access the web and write files\n",
    "2. Define some utilities to help create the graph and agents\n",
    "3. Create and define each team (web research + doc writing)\n",
    "4. Compose everything together.\n",
    "\n",
    "But before all of that, some setup:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "0d30b6f7-3bec-4d9f-af50-43dfdc81ae6c",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-15T08:19:42.364369Z",
     "start_time": "2024-05-15T08:19:42.359273Z"
    }
   },
   "outputs": [],
   "source": [
    "# %%capture --no-stderr\n",
    "# %pip install -U langgraph langchain langchain_openai langchain_experimental"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "30c2f3de-c730-4aec-85a6-af2c2f058803",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-15T08:19:42.395571Z",
     "start_time": "2024-05-15T08:19:42.365662Z"
    }
   },
   "outputs": [],
   "source": [
    "import getpass\n",
    "import os\n",
    "\n",
    "\n",
    "def _set_if_undefined(var: str):\n",
    "    if not os.environ.get(var):\n",
    "        os.environ[var] = getpass.getpass(f\"Please provide your {var}\")\n",
    "\n",
    "\n",
    "_set_if_undefined(\"OPENAI_API_KEY\")\n",
    "_set_if_undefined(\"LANGCHAIN_API_KEY\")\n",
    "_set_if_undefined(\"TAVILY_API_KEY\")\n",
    "\n",
    "# Optional, add tracing in LangSmith.\n",
    "# This will help you visualize and debug the control flow\n",
    "os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
    "os.environ[\"LANGCHAIN_PROJECT\"] = \"Multi-agent Collaboration\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "354568e2-aef0-4af9-8a79-e64d3eea752f",
   "metadata": {},
   "source": [
    "## Create Tools\n",
    "\n",
    "Each team will be composed of one or more agents each with one or more tools. Below, define all the tools to be used by your different teams.\n",
    "\n",
    "We'll start with the research team.\n",
    "\n",
    "**ResearchTeam tools**\n",
    "\n",
    "The research team can use a search engine and url scraper to find information on the web. Feel free to add additional functionality below to boost the team performance!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "4024eb89-843d-4cc3-ab3f-e1eb4d031179",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-15T08:19:44.477064Z",
     "start_time": "2024-05-15T08:19:42.397083Z"
    }
   },
   "outputs": [],
   "source": [
    "from typing import Annotated, List\n",
    "\n",
    "from langchain_community.document_loaders import WebBaseLoader\n",
    "from langchain_community.tools.tavily_search import TavilySearchResults\n",
    "from langchain_core.tools import tool\n",
    "\n",
    "tavily_tool = TavilySearchResults(max_results=5)\n",
    "\n",
    "\n",
    "@tool\n",
    "def scrape_webpages(urls: List[str]) -> str:\n",
    "    \"\"\"Use requests and bs4 to scrape the provided web pages for detailed information.\"\"\"\n",
    "    loader = WebBaseLoader(urls)\n",
    "    docs = loader.load()\n",
    "    return \"\\n\\n\".join(\n",
    "        [\n",
    "            f'<Document name=\"{doc.metadata.get(\"title\", \"\")}\">\\n{doc.page_content}\\n</Document>'\n",
    "            for doc in docs\n",
    "        ]\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1c427982-fadf-4721-a77e-2465df9fc6bc",
   "metadata": {},
   "source": [
    "**Document writing team tools**\n",
    "\n",
    "Next up, we will give some tools for the doc writing team to use.\n",
    "We define some bare-bones file-access tools below.\n",
    "\n",
    "Note that this gives the agents access to your file-system, which can be unsafe. We also haven't optimized the tool descriptions for performance."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "f20a18ca-2709-4c12-84f3-88678591a9fa",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-15T08:19:44.538421Z",
     "start_time": "2024-05-15T08:19:44.479132Z"
    }
   },
   "outputs": [],
   "source": [
    "from pathlib import Path\n",
    "from tempfile import TemporaryDirectory\n",
    "from typing import Dict, Optional\n",
    "\n",
    "from langchain_experimental.utilities import PythonREPL\n",
    "from typing_extensions import TypedDict\n",
    "\n",
    "_TEMP_DIRECTORY = TemporaryDirectory()\n",
    "WORKING_DIRECTORY = Path(_TEMP_DIRECTORY.name)\n",
    "\n",
    "\n",
    "@tool\n",
    "def create_outline(\n",
    "    points: Annotated[List[str], \"List of main points or sections.\"],\n",
    "    file_name: Annotated[str, \"File path to save the outline.\"],\n",
    ") -> Annotated[str, \"Path of the saved outline file.\"]:\n",
    "    \"\"\"Create and save an outline.\"\"\"\n",
    "    with (WORKING_DIRECTORY / file_name).open(\"w\") as file:\n",
    "        for i, point in enumerate(points):\n",
    "            file.write(f\"{i + 1}. {point}\\n\")\n",
    "    return f\"Outline saved to {file_name}\"\n",
    "\n",
    "\n",
    "@tool\n",
    "def read_document(\n",
    "    file_name: Annotated[str, \"File path to save the document.\"],\n",
    "    start: Annotated[Optional[int], \"The start line. Default is 0\"] = None,\n",
    "    end: Annotated[Optional[int], \"The end line. Default is None\"] = None,\n",
    ") -> str:\n",
    "    \"\"\"Read the specified document.\"\"\"\n",
    "    with (WORKING_DIRECTORY / file_name).open(\"r\") as file:\n",
    "        lines = file.readlines()\n",
    "    if start is not None:\n",
    "        start = 0\n",
    "    return \"\\n\".join(lines[start:end])\n",
    "\n",
    "\n",
    "@tool\n",
    "def write_document(\n",
    "    content: Annotated[str, \"Text content to be written into the document.\"],\n",
    "    file_name: Annotated[str, \"File path to save the document.\"],\n",
    ") -> Annotated[str, \"Path of the saved document file.\"]:\n",
    "    \"\"\"Create and save a text document.\"\"\"\n",
    "    with (WORKING_DIRECTORY / file_name).open(\"w\") as file:\n",
    "        file.write(content)\n",
    "    return f\"Document saved to {file_name}\"\n",
    "\n",
    "\n",
    "@tool\n",
    "def edit_document(\n",
    "    file_name: Annotated[str, \"Path of the document to be edited.\"],\n",
    "    inserts: Annotated[\n",
    "        Dict[int, str],\n",
    "        \"Dictionary where key is the line number (1-indexed) and value is the text to be inserted at that line.\",\n",
    "    ],\n",
    ") -> Annotated[str, \"Path of the edited document file.\"]:\n",
    "    \"\"\"Edit a document by inserting text at specific line numbers.\"\"\"\n",
    "\n",
    "    with (WORKING_DIRECTORY / file_name).open(\"r\") as file:\n",
    "        lines = file.readlines()\n",
    "\n",
    "    sorted_inserts = sorted(inserts.items())\n",
    "\n",
    "    for line_number, text in sorted_inserts:\n",
    "        if 1 <= line_number <= len(lines) + 1:\n",
    "            lines.insert(line_number - 1, text + \"\\n\")\n",
    "        else:\n",
    "            return f\"Error: Line number {line_number} is out of range.\"\n",
    "\n",
    "    with (WORKING_DIRECTORY / file_name).open(\"w\") as file:\n",
    "        file.writelines(lines)\n",
    "\n",
    "    return f\"Document edited and saved to {file_name}\"\n",
    "\n",
    "\n",
    "# Warning: This executes code locally, which can be unsafe when not sandboxed\n",
    "\n",
    "repl = PythonREPL()\n",
    "\n",
    "\n",
    "@tool\n",
    "def python_repl(\n",
    "    code: Annotated[str, \"The python code to execute to generate your chart.\"],\n",
    "):\n",
    "    \"\"\"Use this to execute python code. If you want to see the output of a value,\n",
    "    you should print it out with `print(...)`. This is visible to the user.\"\"\"\n",
    "    try:\n",
    "        result = repl.run(code)\n",
    "    except BaseException as e:\n",
    "        return f\"Failed to execute. Error: {repr(e)}\"\n",
    "    return f\"Successfully executed:\\n```python\\n{code}\\n```\\nStdout: {result}\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "504ee1c6-2b6a-439d-9046-df54e1e15698",
   "metadata": {},
   "source": [
    "## Helper Utilities\n",
    "\n",
    "We are going to create a few utility functions to make it more concise when we want to:\n",
    "\n",
    "1. Create a worker agent.\n",
    "2. Create a supervisor for the sub-graph.\n",
    "\n",
    "These will simplify the graph compositional code at the end for us so it's easier to see what's going on."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "e09fb60f-1aac-455b-b67d-8d2e4ccfd747",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-15T08:19:46.559082Z",
     "start_time": "2024-05-15T08:19:44.541330Z"
    }
   },
   "outputs": [],
   "source": [
    "from typing import List, Optional\n",
    "\n",
    "from langchain.agents import AgentExecutor, create_openai_functions_agent\n",
    "from langchain.output_parsers.openai_functions import JsonOutputFunctionsParser\n",
    "from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
    "from langchain_openai import ChatOpenAI\n",
    "\n",
    "from langgraph.graph import END, StateGraph\n",
    "\n",
    "\n",
    "def create_agent(\n",
    "    llm: ChatOpenAI,\n",
    "    tools: list,\n",
    "    system_prompt: str,\n",
    ") -> str:\n",
    "    \"\"\"Create a function-calling agent and add it to the graph.\"\"\"\n",
    "    system_prompt += \"\\nWork autonomously according to your specialty, using the tools available to you.\"\n",
    "    \" Do not ask for clarification.\"\n",
    "    \" Your other team members (and other teams) will collaborate with you with their own specialties.\"\n",
    "    \" You are chosen for a reason! You are one of the following team members: {team_members}.\"\n",
    "    prompt = ChatPromptTemplate.from_messages(\n",
    "        [\n",
    "            (\n",
    "                \"system\",\n",
    "                system_prompt,\n",
    "            ),\n",
    "            MessagesPlaceholder(variable_name=\"messages\"),\n",
    "            MessagesPlaceholder(variable_name=\"agent_scratchpad\"),\n",
    "        ]\n",
    "    )\n",
    "    agent = create_openai_functions_agent(llm, tools, prompt)\n",
    "    executor = AgentExecutor(agent=agent, tools=tools)\n",
    "    return executor\n",
    "\n",
    "\n",
    "def agent_node(state, agent, name):\n",
    "    result = agent.invoke(state)\n",
    "    return {\"messages\": [HumanMessage(content=result[\"output\"], name=name)]}\n",
    "\n",
    "\n",
    "def create_team_supervisor(llm: ChatOpenAI, system_prompt, members) -> str:\n",
    "    \"\"\"An LLM-based router.\"\"\"\n",
    "    options = [\"FINISH\"] + members\n",
    "    function_def = {\n",
    "        \"name\": \"route\",\n",
    "        \"description\": \"Select the next role.\",\n",
    "        \"parameters\": {\n",
    "            \"title\": \"routeSchema\",\n",
    "            \"type\": \"object\",\n",
    "            \"properties\": {\n",
    "                \"next\": {\n",
    "                    \"title\": \"Next\",\n",
    "                    \"anyOf\": [\n",
    "                        {\"enum\": options},\n",
    "                    ],\n",
    "                },\n",
    "            },\n",
    "            \"required\": [\"next\"],\n",
    "        },\n",
    "    }\n",
    "    prompt = ChatPromptTemplate.from_messages(\n",
    "        [\n",
    "            (\"system\", system_prompt),\n",
    "            MessagesPlaceholder(variable_name=\"messages\"),\n",
    "            (\n",
    "                \"system\",\n",
    "                \"Given the conversation above, who should act next?\"\n",
    "                \" Or should we FINISH? Select one of: {options}\",\n",
    "            ),\n",
    "        ]\n",
    "    ).partial(options=str(options), team_members=\", \".join(members))\n",
    "    return (\n",
    "        prompt\n",
    "        | llm.bind_functions(functions=[function_def], function_call=\"route\")\n",
    "        | JsonOutputFunctionsParser()\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "00282b1f-bb4d-4ee7-9bae-e8e6f586f12e",
   "metadata": {},
   "source": [
    "## Define Agent Teams\n",
    "\n",
    "Now we can get to define our hierarchical teams. \"Choose your player!\"\n",
    "\n",
    "### Research Team\n",
    "\n",
    "The research team will have a search agent and a web scraping \"research_agent\" as the two worker nodes. Let's create those, as well as the team supervisor."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "53db0c78-e357-48ba-ae5f-3fc04735a3b7",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-15T08:19:48.810290Z",
     "start_time": "2024-05-15T08:19:46.561088Z"
    }
   },
   "outputs": [],
   "source": [
    "import functools\n",
    "import operator\n",
    "\n",
    "from langchain_core.messages import BaseMessage, HumanMessage\n",
    "from langchain_openai.chat_models import ChatOpenAI\n",
    "\n",
    "\n",
    "# ResearchTeam graph state\n",
    "class ResearchTeamState(TypedDict):\n",
    "    # A message is added after each team member finishes\n",
    "    messages: Annotated[List[BaseMessage], operator.add]\n",
    "    # The team members are tracked so they are aware of\n",
    "    # the others' skill-sets\n",
    "    team_members: List[str]\n",
    "    # Used to route work. The supervisor calls a function\n",
    "    # that will update this every time it makes a decision\n",
    "    next: str\n",
    "\n",
    "\n",
    "llm = ChatOpenAI(model=\"gpt-4-1106-preview\")\n",
    "\n",
    "search_agent = create_agent(\n",
    "    llm,\n",
    "    [tavily_tool],\n",
    "    \"You are a research assistant who can search for up-to-date info using the tavily search engine.\",\n",
    ")\n",
    "search_node = functools.partial(agent_node, agent=search_agent, name=\"Search\")\n",
    "\n",
    "research_agent = create_agent(\n",
    "    llm,\n",
    "    [scrape_webpages],\n",
    "    \"You are a research assistant who can scrape specified urls for more detailed information using the scrape_webpages function.\",\n",
    ")\n",
    "research_node = functools.partial(agent_node, agent=research_agent, name=\"WebScraper\")\n",
    "\n",
    "supervisor_agent = create_team_supervisor(\n",
    "    llm,\n",
    "    \"You are a supervisor tasked with managing a conversation between the\"\n",
    "    \" following workers:  Search, WebScraper. Given the following user request,\"\n",
    "    \" respond with the worker to act next. Each worker will perform a\"\n",
    "    \" task and respond with their results and status. When finished,\"\n",
    "    \" respond with FINISH.\",\n",
    "    [\"Search\", \"WebScraper\"],\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b01c6ee8-a461-4081-8a97-a3a06ec0f994",
   "metadata": {},
   "source": [
    "Now that we've created the necessary components, defining their interactions is easy. Add the nodes to the team graph, and define the edges, which determine the transition criteria."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "1a7a1260-d9f6-4011-b2b1-13fab5126997",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-15T08:19:48.825649Z",
     "start_time": "2024-05-15T08:19:48.811753Z"
    }
   },
   "outputs": [],
   "source": [
    "research_graph = StateGraph(ResearchTeamState)\n",
    "research_graph.add_node(\"Search\", search_node)\n",
    "research_graph.add_node(\"WebScraper\", research_node)\n",
    "research_graph.add_node(\"supervisor\", supervisor_agent)\n",
    "\n",
    "# Define the control flow\n",
    "research_graph.add_edge(\"Search\", \"supervisor\")\n",
    "research_graph.add_edge(\"WebScraper\", \"supervisor\")\n",
    "research_graph.add_conditional_edges(\n",
    "    \"supervisor\",\n",
    "    lambda x: x[\"next\"],\n",
    "    {\"Search\": \"Search\", \"WebScraper\": \"WebScraper\", \"FINISH\": END},\n",
    ")\n",
    "\n",
    "\n",
    "research_graph.set_entry_point(\"supervisor\")\n",
    "chain = research_graph.compile()\n",
    "\n",
    "\n",
    "# The following functions interoperate between the top level graph state\n",
    "# and the state of the research sub-graph\n",
    "# this makes it so that the states of each graph don't get intermixed\n",
    "def enter_chain(message: str):\n",
    "    results = {\n",
    "        \"messages\": [HumanMessage(content=message)],\n",
    "    }\n",
    "    return results\n",
    "\n",
    "\n",
    "research_chain = enter_chain | chain"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "110f59bed6134685",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-15T08:19:51.936523Z",
     "start_time": "2024-05-15T08:19:48.827798Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/jpeg": "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L7HktlprlFSV1BHOHEU9ypn007NHEeNG8BzddNRqOwgrZrhmMJwdcbYFm8Lv/V5f+dmf5KmWEs3hd/6vL/zsz/JUy9/7G/iXf8f/AKpedl/8H4u7REX0D54REQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQYV6+89f/uJP4SouxRodilnaRqDRQgg/wC7ClqogbVU8sL9dkjSx2nmI0K4mn4RW2kp4oIbreo4YmhjGCt5NaBoB2LnynJ4yq1FvOwmJx7nfkmUU2Mc7ijL/R+4ZegGN/VcP/2r5/o/cMh//AMb+q4f/tUpfcqofli9+u/Yn3KqH5Yvfrv2LzfRlz13zduuWOnuhqYII6aCOGFjYoo2hjGMGga0DQADzL0Wy+5VQ/LF79d+xPuVUPyxe/XfsWfof+7HZLT0ha5S1qKNOi3S1vFjhc++3+93SS4C611JugqOrb1cU7mM5AdugHNS79yqh+WL3679ieh/7sdknpC1ylH+QcIcHyy6y3O9YjZbtcZQ0SVVZQRyyvAAA1c4EnQAD9i17uAPDRwaHYDjhDRo0G2Q8hrroPF85P8AzUofcqofli9+u/Yn3KqH5Yvfrv2LSPsuuNkXvmprtid9PdDl8axSy4bbjb7DaqOzUJeZe5qGBsMe86au2tAGp0HP5l0fC7/1eX/nZn+Spl6/cqofli9+u/Yt3i+J0eJQVkdJLUzmrn7omlqpese5+xrO3zbWNH7F25HkeqVV11V52dGHHnE8fc5spyqi7bzKYbtERdryxERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERBXfoIfATJ+frp/mnqxCrv0EPgJk/P10/wA09WIQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREFd+gh8BMn5+un+aerEKu/QQ+AmT8/XT/NPViEBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEXE3LiWx8rorFQOu5adrquSTqKXX8V+hL/wArGkeTXtWsOaZa7mKOyx/imSZ2n7dB/wBlvoZj8UxHvn6OmnJ7tcYxSklFGvhnl3xa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EREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERB//9k=",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from IPython.display import Image, display\n",
    "\n",
    "display(Image(chain.get_graph(xray=True).draw_mermaid_png()))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "63ee8f2c-fbde-427b-ba54-ae0c7ce5fbfb",
   "metadata": {},
   "source": [
    "We can give this team work directly. Try it out below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "912b0604-a178-4246-a36f-2dedae606680",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-15T08:19:51.952470Z",
     "start_time": "2024-05-15T08:19:51.937879Z"
    }
   },
   "outputs": [],
   "source": [
    "for s in research_chain.stream(\n",
    "    \"when is Taylor Swift's next tour?\", {\"recursion_limit\": 100}\n",
    "):\n",
    "    if \"__end__\" not in s:\n",
    "        print(s)\n",
    "        print(\"---\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "749b99ab-f6f0-4c5d-a90b-10102465d186",
   "metadata": {},
   "source": [
    "### Document Writing Team\n",
    "\n",
    "Create the document writing team below using a similar approach. This time, we will give each agent access to different file-writing tools.\n",
    "\n",
    "Note that we are giving file-system access to our agent here, which is not safe in all cases."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "1bcdbf44-9481-430c-8429-fa142ed8a626",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-15T08:19:53.677722Z",
     "start_time": "2024-05-15T08:19:51.953933Z"
    }
   },
   "outputs": [],
   "source": [
    "import operator\n",
    "from pathlib import Path\n",
    "\n",
    "\n",
    "# Document writing team graph state\n",
    "class DocWritingState(TypedDict):\n",
    "    # This tracks the team's conversation internally\n",
    "    messages: Annotated[List[BaseMessage], operator.add]\n",
    "    # This provides each worker with context on the others' skill sets\n",
    "    team_members: str\n",
    "    # This is how the supervisor tells langgraph who to work next\n",
    "    next: str\n",
    "    # This tracks the shared directory state\n",
    "    current_files: str\n",
    "\n",
    "\n",
    "# This will be run before each worker agent begins work\n",
    "# It makes it so they are more aware of the current state\n",
    "# of the working directory.\n",
    "def prelude(state):\n",
    "    written_files = []\n",
    "    if not WORKING_DIRECTORY.exists():\n",
    "        WORKING_DIRECTORY.mkdir()\n",
    "    try:\n",
    "        written_files = [\n",
    "            f.relative_to(WORKING_DIRECTORY) for f in WORKING_DIRECTORY.rglob(\"*\")\n",
    "        ]\n",
    "    except Exception:\n",
    "        pass\n",
    "    if not written_files:\n",
    "        return {**state, \"current_files\": \"No files written.\"}\n",
    "    return {\n",
    "        **state,\n",
    "        \"current_files\": \"\\nBelow are files your team has written to the directory:\\n\"\n",
    "        + \"\\n\".join([f\" - {f}\" for f in written_files]),\n",
    "    }\n",
    "\n",
    "\n",
    "llm = ChatOpenAI(model=\"gpt-4-1106-preview\")\n",
    "\n",
    "doc_writer_agent = create_agent(\n",
    "    llm,\n",
    "    [write_document, edit_document, read_document],\n",
    "    \"You are an expert writing a research document.\\n\"\n",
    "    # The {current_files} value is populated automatically by the graph state\n",
    "    \"Below are files currently in your directory:\\n{current_files}\",\n",
    ")\n",
    "# Injects current directory working state before each call\n",
    "context_aware_doc_writer_agent = prelude | doc_writer_agent\n",
    "doc_writing_node = functools.partial(\n",
    "    agent_node, agent=context_aware_doc_writer_agent, name=\"DocWriter\"\n",
    ")\n",
    "\n",
    "note_taking_agent = create_agent(\n",
    "    llm,\n",
    "    [create_outline, read_document],\n",
    "    \"You are an expert senior researcher tasked with writing a paper outline and\"\n",
    "    \" taking notes to craft a perfect paper.{current_files}\",\n",
    ")\n",
    "context_aware_note_taking_agent = prelude | note_taking_agent\n",
    "note_taking_node = functools.partial(\n",
    "    agent_node, agent=context_aware_note_taking_agent, name=\"NoteTaker\"\n",
    ")\n",
    "\n",
    "chart_generating_agent = create_agent(\n",
    "    llm,\n",
    "    [read_document, python_repl],\n",
    "    \"You are a data viz expert tasked with generating charts for a research project.\"\n",
    "    \"{current_files}\",\n",
    ")\n",
    "context_aware_chart_generating_agent = prelude | chart_generating_agent\n",
    "chart_generating_node = functools.partial(\n",
    "    agent_node, agent=context_aware_note_taking_agent, name=\"ChartGenerator\"\n",
    ")\n",
    "\n",
    "doc_writing_supervisor = create_team_supervisor(\n",
    "    llm,\n",
    "    \"You are a supervisor tasked with managing a conversation between the\"\n",
    "    \" following workers:  {team_members}. Given the following user request,\"\n",
    "    \" respond with the worker to act next. Each worker will perform a\"\n",
    "    \" task and respond with their results and status. When finished,\"\n",
    "    \" respond with FINISH.\",\n",
    "    [\"DocWriter\", \"NoteTaker\", \"ChartGenerator\"],\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aee2cd9b-29aa-458e-903d-4e49179e5d59",
   "metadata": {},
   "source": [
    "With the objects themselves created, we can form the graph."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "9c5c644f-8966-4d2e-98d2-80d73520e9fe",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-15T08:19:53.693123Z",
     "start_time": "2024-05-15T08:19:53.678906Z"
    }
   },
   "outputs": [],
   "source": [
    "# Create the graph here:\n",
    "# Note that we have unrolled the loop for the sake of this doc\n",
    "authoring_graph = StateGraph(DocWritingState)\n",
    "authoring_graph.add_node(\"DocWriter\", doc_writing_node)\n",
    "authoring_graph.add_node(\"NoteTaker\", note_taking_node)\n",
    "authoring_graph.add_node(\"ChartGenerator\", chart_generating_node)\n",
    "authoring_graph.add_node(\"supervisor\", doc_writing_supervisor)\n",
    "\n",
    "# Add the edges that always occur\n",
    "authoring_graph.add_edge(\"DocWriter\", \"supervisor\")\n",
    "authoring_graph.add_edge(\"NoteTaker\", \"supervisor\")\n",
    "authoring_graph.add_edge(\"ChartGenerator\", \"supervisor\")\n",
    "\n",
    "# Add the edges where routing applies\n",
    "authoring_graph.add_conditional_edges(\n",
    "    \"supervisor\",\n",
    "    lambda x: x[\"next\"],\n",
    "    {\n",
    "        \"DocWriter\": \"DocWriter\",\n",
    "        \"NoteTaker\": \"NoteTaker\",\n",
    "        \"ChartGenerator\": \"ChartGenerator\",\n",
    "        \"FINISH\": END,\n",
    "    },\n",
    ")\n",
    "\n",
    "authoring_graph.set_entry_point(\"supervisor\")\n",
    "chain = authoring_graph.compile()\n",
    "\n",
    "\n",
    "# The following functions interoperate between the top level graph state\n",
    "# and the state of the research sub-graph\n",
    "# this makes it so that the states of each graph don't get intermixed\n",
    "def enter_chain(message: str, members: List[str]):\n",
    "    results = {\n",
    "        \"messages\": [HumanMessage(content=message)],\n",
    "        \"team_members\": \", \".join(members),\n",
    "    }\n",
    "    return results\n",
    "\n",
    "\n",
    "# We reuse the enter/exit functions to wrap the graph\n",
    "authoring_chain = (\n",
    "    functools.partial(enter_chain, members=authoring_graph.nodes)\n",
    "    | authoring_graph.compile()\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "58e7d1e48a9c39a5",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-15T08:32:13.913188Z",
     "start_time": "2024-05-15T08:32:11.598993Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCADtAjcDASIAAhEBAxEB/8QAHQABAAIDAQEBAQAAAAAAAAAAAAYHBAUIAwIBCf/EAFUQAAEDBAADAwgDCggLBwUAAAEAAgMEBQYRBxIhExQxCBUiQVFWldEWMmEXIzZCVWJxk5SzM1JUdoGhouEJJDRDU3J0dZGSsTVjc4KywdIYJbTC1P/EABsBAQACAwEBAAAAAAAAAAAAAAADBAECBQYH/8QAPBEBAAECAgYHBgQFBAMAAAAAAAECAwQRExQhMVHREhVBUpGh8AVTcZKisSIygcFCYWLS4TM0Y3KCwvH/2gAMAwEAAhEDEQA/AP6poiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAtX9KrL+WKD9pZ81tFRWB2K2zYNjsklvpXvdbqZznOhaSSYm7JOlFev28Nb0lcTO2I2fryXMPh9YmYzyyXD9KrL+WKD9pZ80+lVl/LFB+0s+arv6PWv8m0f6hnyT6PWv8AJtH+oZ8lzutcP3KvGF3q7+ryWJ9KrL+WKD9pZ80+lVl/LFB+0s+arv6PWv8AJtH+oZ8k+j1r/JtH+oZ8k61w/cq8YOrv6vJYn0qsv5YoP2lnzT6VWX8sUH7Sz5qu/o9a/wAm0f6hnyT6PWv8m0f6hnyTrXD9yrxg6u/q8lifSqy/lig/aWfNPpVZfyxQftLPmq7+j1r/ACbR/qGfJPo9a/ybR/qGfJOtcP3KvGDq7+ryWJ9KrL+WKD9pZ81l0VypLkxz6SqhqmNOnOhkDwD7DoqsPo9a/wAm0f6hnyW24WUsNHdsqjghjgjFTAQyNoaP4BvqCuYbF2sXNVNFMxMRnty4xH7q9/CaGjp9LNYSIitOcIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAqY4ffgFjf+7Kb901XOqY4ffgFjf+7Kb901cv2n/tv/ACj7VOx7O31fo36Ii8m7aGx8X8SmzOTFIrqZ75FIYXwQ0sz42yCPtDGZQwxh4YC7k5ubXqUa4a+URYc+seQXOohq7RDZp6vt3VFDUtjFNDK5gkMj4mt5iG8xjG3N2QRsFRZ3nXH+OTG4XZ8nooLpdy7JKavoD5mni7Eh1bDOejZdtjGmu9PXVvTZ1lpuGZ4fw/4kYxY8fvVNlsN0udyoK4W8vpZ4JqvtA+CU/e3y9lK4tjJ3zM0Qr2ioy2b5y7fFU0lWfj2eC2sf42YXlFqvlwt95L6eyQGquDJqSeCaniDXO5zFIxry0ta4ghp3o62ormXlP4tY8NOQWXvd+p++UVK18Vvq2wuFRJy87ZOxLX8rQ86bv0mhnRzmg1dBjdfU5BnlXbLNnFVQXPAKq3wVuTRVElRVVbS9xjDZNuj2JRys5WBx5+QH12Hn+K3WbyZceoLdaKmpuFrgstU+1wRanLaaWnkljaw6POGxu9Hx2NeKzorVNUZ9sx2saS5NM/yhcVivdLkdoprlRdv3Wobzx95ppKeTW9elHI1r2+Hg4BZ61WMZDHlNlp7nFRXC3xzc2qe6Uj6WobpxHpRvAc3etjfqIW1VGYynJbjbAsvhr/23lf8AtEH7hqxFl8Nf+28r/wBog/cNXe9j/wCpc/6/+1Ln4/8A0f1T1ERehedEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAVMcPvwCxv/dlN+6arnUDo+D1rt9JBS010vMNPAxsUcba3o1oGgB09QCr4nDxirOj6WU5xPlPNfwl+mxMzV2q0/8Ap+4Ze4GN/C4f/iv2TgFw0le578Cxx73ElznWyEkn2n0VaH3KqH8sXv8Abf7k+5VQ/li9/tv9y5vVlz333Xdcsd3yhpaCgprVQ01FRwR0tHTRthhghaGsjY0ANa0DoAAAAPsWQtl9yqh/LF7/AG3+5PuVUP5Yvf7b/co+qP8Aljwlvr9rhLWoq08milreKOLZRX3293SSot+T3G1QGCo7MCCF4awEa6nR6n1q3fuVUP5Yvf7b/cnU/wDyx4Sz1ha4SgORcJcKy+5uuN8xOzXevc0MdVVtDHLIWjoBzOBOgtYfJ/4ZnW8Axvp4f/a4f/irR+5VQ/li9/tv9yfcqofyxe/23+5SR7LrjZF77tNdsTtmnyhFcXw+xYTQSUOP2ehslFJKZn09BTthY6QgAuLWgDemtG/sCkfDX/tvK/8AaIP3DV7/AHKqH8sXv9t/uW5xfEKPExWd1mqqiSre2SWSrl7RxIaGjrrw0FdwmD1WquuqvpTMZbp4xP7K+IxVu7b6FMN6iIrrlCIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIg538iT8BM6/nxeP3rV0Qud/Ik/ATOv58Xj961dEICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIg538iT8BM6/nxeP3rV0Qud/Ik/ATOv58Xj961dEICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIvmSRsTHPe4MY0Euc46AHtKg1dxNfVSclgtZucX8uqZu70zvtYeVz3j7Q3lPTTj4iSmiqvbHJJRbquTlTGadoq2dmmWnqKSys+wvmdr+nQ/wCi/Ppnl38msn/NMt9FHejxT6pe4LKXJH+Ek4KTcS+C8OTW9jpbph75awxj8ekkDRUaHhtvZxv2fxY3e1Xb9M8u/k1k/wCaZeVVlOUVtNNT1FDYp6eZhjkik7VzXtI0QQfEEdNJoo70eJql7g/ld5EPAs8ceONsgraYzY3ZdXO6Fzdse1h+9wnfQ9o/lBHjyh5Hgv7QLl7yfOEU/k42e90GOQWyoN2rnVc1RVukMgYNiKHYA21gJ1vqS5x9eha/0zy7+TWT/mmTRR3o8TVL3BZSKtfpnl38msn/ADTJ9M8u/k1k/wCaZNFHejxNUvcFlIq7gz7IqZ4NXZaGsh31NDVubIB7Q17Q0/0vCl2PZPQZPTvko3vbJEQ2annjMcsJPgHNPXro6PgdbBIWtVuqIz3x/Kc0Vdm5b/NDbIiKJCIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiCus0urr9fJrIxx820IY6sDXdJ5nDmbC4fxWsLXkfjc7PUCDjLW2d7pqq+yyfwr7vWB3t02ZzG/2Gt/qUf4wVuU27hzeKjDITPkUbYzAxsbZXhnaN7UsY4hr3iPnLWk6LgB18FJf2V6ON0bOfjL0dimLVqJj4pkioKx8T7lUy8OobfmFRkMVyyOptt0fW2uKjqmBlHLJ3aaLkHZyMexpJAaSNeIPXCz7idl9JlOY2q2Xzze2myvH7RRyd0hl7vBVxQmYac30tukcep2PAEKtkk0tOWfrdm6KRc5ZxxeyzglW5jarjchmT6ax094tVXVUsUEsUktWKTspREGMe0Pex4IDToOBPrHvZso4r2aW5yXOnvlTaBZ62eWvvlDbKZ1FVRxF8RiFLNJzscQ4Fr2kjTTzHqmRpYzyyl0MsW6XahslE+suNZT0FIwta6oqpWxxtLnBrQXOIAJcQB7SQFQVPk2f4/wZxjiPc8tluzXRWy53e2st9NHCKF7R3jkLY+fmDZWyE82txHlDWu5VgcScyyPI8HzPKKO8Rx41R5HQW610MlBS1MFXFHVRU9Q9xkjdzB08jy0g7Bp2FpGztkxN2IjPJ0sio6lzjJrXxrrrdld/qrFbJax7bJam2uN9FdaYQbAZV65hUB/MTGXDo3TWnexHrNxLzqPCsO4mV+QQVFoyC6UsE2MNoYhDTUtTP2UfZzAdq6VnMxxLiQfSGgjOljg6SWHWsqaSZlztmhdaVpMQLuVs7fEwvP8V32+B04dQqr4LXLL8zuOQ3m85RJJbLfkN0ttLaYKKBjHwRTvjjMsnJzlzegHKW9Gjm5iSrgW9FU26ulDbZdp2xslYVnutPfbVSXGlcXU1VE2aMnx0RvR9h9oWYobwne52JPZ/m4rhWxx6Ghyipk0P6Oo/oUyU92mKLlVMdkvM1x0apgREUTQREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQERai55hYrLebdaLherfRXW4ktoqGoqWMnqSNk9mwnmf4HwB8EG3RV/Q8a7BfrtmlnsDK293zFYXOrKCKkkiMkoDtQxPkaGvcS3Xokj0m9eq1F1yriplfDC1XTEcUteMZbV1ZZUWzMahz46WmBkHaE05JLzqMhvq5iCOnULXWNcblSWihmra+qhoqOBvPLUVEgjjjb7XOJAA+0rk/y4OK/FHyeq3F+IWMX23VGKulFqqcYuFJzMdVvjme2YvZyve3lYenO3lcxp04OIbyrw18umksTMott44Zuy6PL6jnuFHNfJnskc5zvvccckcmmemQGD1Bo2dIP6Eyz0Yvs1dbqynuFjvuq2hraWZssMkgaGysY5pIP1BINE75pP4pWLlWPfSmxVNsFzuFnMxYRW2qfsaiItcHAtcQR4t0QQQQSCNFfWC5tiOWVMXDOmxOuxytt1np7hVWyK2ugpLQ+RkcjadszWtYJm9sCOTp6LuuwQtpXY5kdjk5WUoyGjH1Z6Z7IqkD8+Nxawn7WuG+umDoFNVTpvxRO3w/Xn6y7GGxNPR6FxV0fk9WGOx90bdr35187+ffpAaphr++dn2fac3Z9nrs/Q5OTl16vWopnnk7yss8zLBcL1dLleMmtFzudbV10YniZTvY2SaN5a3lLWNLg0b0QAxoADVdxrri3o7G70HesCmB1/SHEL884V/u5ev2T+9a6vd4LczYmMs4QS28AcbioskhvVRc8tqMhp20dfW32oEszoG75ImFjWNja0uLhyAHm672AsrH+DsNjt9yoqjLMnvtNWUL7cI7tXslEETholgEbQX6/HfzO+3xUx84V/u5ev2T+9POFf7uXr9k/vTV7vBt0rMdsMG04ZbbVg1HiRa+stFNbWWrlqSHOlgbEItPIABJaOugPE9AtFVcGrBPwsoeH8bqqksVGykbG6B7RMe7zRzNJcWkEufGC4668zta3sbOzcQaDJLfWV1npau8UdHK+CpntzWVDYZWAF8bixx09oI23xGx06r9xPPaXOseo77j9tud2s9Y0up6ymp+aOQBxadHfqc0g+wgpq93gzpLU9sNLW8GaC6ZpS5Bcb9f7lHR1wuVLZ6qsa6hp6kMLWyMZyBw5Q52m85aCSdLW2vydcctV1t0zLjep7NbK43K347PVtdbqSo5i5r2M5A/0XOLmtc8taT0AVh+cK/3cvX7J/ennCv8Ady9fsn96avd4NelZ4w12FYRQ4JQ3CloJaiaOuuNVdJDUua4iWeV0jw3TR6ILjoHZ14k+K21zrjb6N8rInVE59CGnYQHTSH6rG79ZPRfsDL9XvDKTGq1hJ12tdJHBGPtPpF//AAaVLMXwk2yqZcrrPHX3VoIjMbC2GmB6ERgknmI6F56keAaCQsxa6E53PDPbPhuR3MTbt05UznLScOs+xOK8V3Dyjv8ADXZZj1OJ7tShkgMbn8r3yczmhpBdKD0J1zaPUFTq1Xmgv1G2stldTXGkd0bPSTNljP6HNJC5p8ojy1sK4DZrcMZveFX24Xd9Mz/G200EdNWQSMBPJMX87mg7afQ1zNcPVtc3YL5U2N8V7hj/AAawvhbdcJsN9vcTn1OMX98VZTlzwZKhobAeVsbWmRw3rljPVoGxpVVNVU1TvlwJnOc5f0zRQW44TlIynFauz5xUW/HbXCKe42apoYqp90ABAe6of6bH/V2W+Oj7V40V14kW+5ZrPdrLY7laKSJ8+OU9oqZGVdaQHkQzmX0GPOmDmHo7d7AtWFgIqlr/AChKXDeFtqzTPMZveItrKw0U9uNOayajcDJp8nZA/eyIiQ7X4zenpBTubPsbpsvpsUmvlBBktVTd7p7TLO1lTNF6fpsjJ5nAdm/eh05ST4IN+i+WPbINtcHDZGwd9QdEf8V9ICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAi02V5nYMEtJumSXu32C3B4j73cqplPGXkEhoc8gFxAOgOp0tFdeL+P2jibY8Dk79NfrvSurYDT0b308cIEhD5JgORuzE4Ab3st6dQUE2RVxRZnnWSQZ3S0WFDHK6188Ngrr5VskpbtKO0AeWRHnji2xh2epEg11BCwrlg3EXNsIxinu+bQ4fktLU94vEuKU/aU1YwF2oY3TgPY3XJs+PRw0d7QWooTeuM+GWXEr5kvn+luVoskghr5bS7vroJCWgRlsPMebb29NdN7Oh1X79yKwHip90J7q+TIBR9yjDqyTu0UetHlh3y7PTZIPgD4rd4xhOPYTDUw49Y7dY46qUz1DbfSsgE0h8Xv5QOZ32nZQRG7cWLo+PA6nGMJu2TW3JnsfUVYc2kFqpyYyZZ2ydeYNkcQzxJjcNjotnQt4gz8Q74yvdj9NgfdAy1y0hmddDUER7fKHDsgwHtQANk6aT4nUlvmQWvGLdLcLxcqS00EXWSqrp2wxM/S5xACo28+WthNRcZbTgluvnFG9MPKabFqB80MZ9RkncAwN/OaXBBJ4OA9XknCupw3iHml1zV9VViqmukLRbZXNBaRCBEejNg7G+ocQpNdcJwTH/M1/vVvtEMmOUzaagu93LHPoYgAByzSnbT0+tvfj16lUFn/EnjV9HnXzLLziXk9Ym+QRCoq3i8XUucCQxjR96c4ta48oHMNE66HXxbfJqsdXxgtttzKwZbxcjdRd/mzLKLqJLXTOPNyxRUwIa7Zbos07lDmnWjtBOb15Z+CvuMtpwqlvPE+9sPKaTEqB9TGw+ovnOow384OdpQHJ+M3GK/5fjWL19XjnBObJpDHbYJY3327SgDq/0AKdg8PrkEEgdVaeO8A6y58NMiwrPLpQXCyXOtEtNQ4zQC0RUNM1zC2BhiOyD2YLievpuGyNK1bFjluxq022226lbT0dtpWUVI0uL3RQta1rWB7iXEaY3xJ3yjaDivIvI/v/ABPx7ihBmNNlF/yCggkbil8u+Sxy9/qWc7mujpQGxU0Ujmxs5X70JH+k3o4ZHkj/AOD2tmCUdNlHE+3w3PKxK2ektXbc9Pby07BeWHllk318XMGhrZ6jt5EBERAREQFQ/lo8dPuE8D7pcKOcRZFdd221AH0myvB5pR/4bOZwPhzcgPir4VM+UX5KuJ+U2MfGUXG9UAsneO7+aJ4Y+ftuz5uftIn712Tda14nx6aDgn/Br8dvufcV5sKudQWWXKy2ODnd6MVc3+CP2doNx9PFxj9QX9GeHM1ztGW5VijMJpMXw+z92NkrrcGMgrRKwvm+9gDlc150dDRJPU+vifyaPIMwTiTZ77fK2/5VbbjZcnrbbSSWysp4+VlPI0RyEugcef1kggbHQBdqcVLc22XzF85rs7fh2PYxJPLdKaok5aK4RzMETWzbe1oLXEcjiHHmdoDZCCx0X41we0OaQ5pGwQdghfqAiIgqvyifJ3xvyjcHfY72zutfBzSW27RMDpqKU66j+Mx2gHM3ogDwIa4cOeS55COaUHF/KxlNXesKONwCO2X+ySugfUVMp02WmlMZZLF2TZWyN2CO1Y0gEuA/puiDnXu/lF8Kv4GosHGezR/5ucCz3Yj2Bw3A7Q9Z6krNsnlm4VDcYrRnVDeeFt8eeUUuV0ToIZD6zHUDcbm/nEtV+rAvdhtmS22W33e3Ul1oJRqSlrYGzRP/AEtcCCg+7TeKC/W+GvtldTXGhmHNHU0krZY3j2tc0kH+hY8+LWWqv1NfJrRQTXqmYY4LlJTMdUxNIILWyEczQQ5w0D6z7VSV38jDEqC4TXXh5eb7wrvMh53S41WubSyu9Xa0zyWOb+aOUdFhG7eUbwo/y+12HjNZY/Gptrxabry+tzonbhd/qs6lBYlBwAxbG7bm8GLG4YnXZe909xulsrZDUid3Oe2jdIXiN23uPogDqvC44NxCseI4paMTzaKoq7dOPOdyyam71PcINkkFzdcr+vQ/YFGMX8tDh1dLoyzZNLceHGQno615jRuoHezYkduPW/Alw37FeNFXU1ypIqqkqIqqmlbzRzQPD2PHtDh0IQRKO/5r91OW0vxWl+g/dO1jyIXFomE+huI0+uYgknTug6foC0VF5QVlp8GyLLcosmQ4LaLDVClq35DbnRudtzGtliawvdJGTI0BwHt6dCrRXy9jZGlrgHNI0QRsEII/beIeM3W3WGup77Qinv8ACKi1dtMIn1rCGkGJj9Od0e06A2OYe1SJRfJOGGJ5fWWCrvGP0FfU4/O2ptU0kI5qKRrmOBiI1yjcbOg6HlGx0WFbeFVus/EO/ZnRXG7R3a80wp6inlrXyUTS1sbWyNpyeUPAiaNj1F38YoJqiqWmw/irhPCyrttlzK25vmgqxLS3LLaQ01OINt3E9tP6TiAHadvZLuvQBbu5ZnmVlyPD7S7CX3mkuUIF3vtBWsjp7bMAOb70/cj2E82j7NDqdoJ+igdl4049ecmy6yFlxt8+LsMtwqbhRvhpuzG9yRyno9vou6j2Fb/GM6x3NLJS3ixXugu1rqnmKCrpKhr45HgkFgIP1gQenj0Qb1ERAREQEREBERAREQEREBERAREQEREBERARFjXK5Ulmt9TX19VDQ0NLG6aeqqZBHFFG0bc97iQGtABJJ6BBkoq4ybj7ieP4bZ8opJa3J7Pd6w0NFNjdI+vM8oLweUR76AxSDfh6K2VTl2VM4q0uOwYVLNijqM1FRlRr42sil07lhEBHO47aNkHpzDogmqKrrbjnE/JcYy+3ZTkVpsFbWzllluGLQyGSipwejniboZCAN6Oup16l71nAiyZLacKp8trbllNfisjailuFTVyQSTTtLSJZRE5oe4FjTo9Nj17KCVw59jdTl9TikN8oJ8mpqfvc9oiqGvqYYvQ9N8YO2g9ozWx1DgR4qEU3Hj6XcMbrl2B4neMrmo6wUUNqqIjbZqt249vZ2zfqASA8xH4rvYp/TYfYqPI6vIILLb4b9VsbFUXRlKwVUrAAA10uuYtAa0AE66BbdBXlyn4mXe8YRV2mCxWOxSxNqMkoLoZJq+FxDSYIHx/eyRt4Lj020EHRXpbeGt4+lGX117zS43ux3yA0tNYnQsght0RGiI3M9Jzjt3pHR6j2bU/RBAMX4EYPiuC0eHxWGC54/SVLqyOkvO68duSXGT79zeltxI9mzrSnrGNiY1jGhjGjTWtGgB7AtbkmU2bDbTLdL9dqKy22Lo+ruFQyCJp9QLnEDf2Khrr5cGJ3SvltXDjH8h4qXhh5SzH6B4pY3f8AeTvADW/nAOCDo1azIcms+JW2S43y60Vmt8f16qvqGQRN/S5xAXPYt/lL8Wf8rr8d4L2aTxho2C7XUNPqLz96HT1tLSFpb95OvCLhnYbnnnEStv8AxbuFplZDU1N5qZLnJHM9zGiJtMw8g2ZGeg8HQcOukEpu/lt4dXXCW1cPrPf+Kd5YeUw41QPdTxu/7yd4DWt/ObzBa2tqPKL4h0c1Xca/GOBmONaXyyFzbrcoo/WXPcRA0a9fokKzrZW5JHV4PHg+K2a1YDWUrau4iuDqKqo2OYCyKOmYzTZPSGw7oOVwOuhWRYuDzKW4ZxJkGR3bMbZlLy19lvL2yUVFT7fqCGPXot1IQTvqGt6bG0FAVfA3hvaazDr7faTL/KHuOQVYgprxNVecqKlZzDnmc1r2xshA2QCHj0SFfWPYfldszC+W0fR6ycMe4d2tNvsNO+mro5XNZzyvcNMZo9o1vJ+aehCndksVtxm001rtFvpbVbaZvJBR0ULYYYm73prGgADZPgFnIILgvBuwYRhdHjchq8npaapNaKnJJu/zvqCSTKXPGg7ZJHKBrZ14lTpEQEREBERAREQEREBERBzt5Ef4B51/Pi8fvWq8stxK0Z3jdwsF+oY7lZ6+Iw1NLKSGyN3vWwQR1AOwQRpUb5Ef4B51/Pi8fvWrolBBeDeZS5nhzpZcWr8Pdbaye1C2V7TsNgeY2vY4gc7C0DThsb2NnW1OlBY6HJ7XxerLlXZLROwevtsNLRWecNZPFcGyEuLDyjma6Pr1cXb8AAFOkBERAREQEREBERBp8pw6w5xa323IrLQXygd401wpmTs37QHA6P2+Koyu8i+0Y1Vy3DhXmGQ8K7g93Oae2VTqq3SO9slLKSHfo5gPsXRaIObDmvlEcJumSYfaOLFlj8bli03c7gG/xn0zxyvd+bGP6VIsJ8szhfl1x80193nwrIGkNks2W07rdURu9QJf6BP2BxP2K8VG834bYrxKt3ccqx623+lAIayvpmylm/WxxG2n7WkFBIYZo6iJksT2yxPAc17DtrgfAg+sL7XNc/kbPwaZ9Xwf4iZDw3l5i8Wp0xuNqcfHrTzE+PtLjr2LzPFbj5wl9HOOHFJxDs8fR16wSY95Dfa6kk9J7tePLytHtQdMIqY4eeWBwr4jVYt9PksdivYdyPs+QsNBVMf/ABNSaa532Mc5XMCHAEHYPUEIPmaGOoifFKxskT2lrmPGw4HoQR6woNm/ArA+IeFMxG9Y3SPx2Oo73HQUfNSMjm9L743sS3TtveT7S4k7U8RBCLjwykrOJtky+nym/W+nt1IaOTHKeqAtdWzUnK+SLWy9pkBDt/iNGvHeBbrXxLx6jzmpqL5asuqp3yT41QyUfcW0uzIWQTvaTztG428/1tNJPU9LGRBV124p5Xh+FY1cb7w7utzvtwqe7V9rxZza4UPVwEpeeXbNBpPs5vHptb/7r+J/dQ+52boRl/dO/C392l0Ydb5u05eT+gu31HRTJfJY1z2uLQXN3okdQg1tiymzZRHPJZrvQXeOnkMMzqGpZMI3jxa4tJ0R7D1W0UDn4G4ScTyDHKGxQWO132Ttq9lmJonyybB5w6Mgg+iPDx9e9lYF04SXaGiwWixjOrxjlDjUjG1ET2trHXWAGPmjndJ15i1jgH+ovJ0dBBY0tVDA7lkmjjcRvTnAFfHnCl/lMP6wLlvym85yfEeKGI2yp4hUOA47eZq5zbkKemeY4IqanLGSuqWFvOZzPot16L2DqQsOpyrIcat/Diei4inOKHI8sho33NtHRtZLSGnqC6JphYG67SIHmHpbBG9dEHWHnCl/lMP6wJ5wpf5TD+sC5MwfjxdLrduJGPXkCluFtrrsLBX8jQyrhp3O3GBrRkh2zYI25jmnrpxWFh/FzMa+pxAmY3met4YPyOSgEEbTWXIGn5Xba0Ec3aObytIb6Xh0Gg7A84Uv8ph/WBPOFL/KYf1gXJfC7MMiv/DG8Zm/iVDk83mOWaW1Q22mh81Vwj5yw8o5xyEObyS7J8VoLx5UFvk8nrHK21Z5ZpuIlTTWYVMEM9NJUumkmp21QMGiAeV0uwGjl661roHbTXB7Q5pDmkbBHgV+rHt/+QU3/hN/6BZCAiIgIiICIiAq84y4/fb/AEOOttV8t1os8N3hfkFNdWNdBcbYWubNTHma4bfto0dAgnZ9RsNQHjzieNZrwgyi25i2rdjTKQ1taaEkThlORPtmgTzbiHQDr4etBMbPZbfj1uht9qoKa2UEIIjpaOFsUTNnZ5WtAA6knp7VmrR4PldvzrDbJkVplkmtl0o4qynfMNSFj2Bw5h6ndeo9u1vEBERAREQFXHGzjxjfA2xQVV2dNX3euf2FqsNvb2lbcZj0DI2DrrZG3eA2PEkAxnjV5Rn0NvkOC4Na/ppxQr2bp7NA77zQtP8An6x4IEcY2DokE7H1QQ5fnBXycvobfJs6zq6fTXihXM1UXmdv3mhad/eKNhAEbBsjYAJ2fqglqCJYd5Pt/wCNeQQZ5x4igrHs26zYEx3aW+1Md+NOPCaYjx3sfp6NZ0fabNQWC3w0Fsoaa20MI5Y6akhbFEwexrWgAf0LMRAVR3zhzUcILBlV74P4na5snvFdDX1tsqqp8EFXykCQRjfJHI5vNo+i3mdt29aNuIg1Fryi3XK51NobXUZvtFDFNXW2GobJLSiQbbzAaIB0dEgb1tbdQnIeG9DDdr3mGMWiz0nEaqtj6CnvNZC7ld4GMTcnVzQ5rNn62mgeAAXxifEA08eM4/m9dZbRxEudCamSy0VXziQsOnmLm0SPXrr4O0XBpcgnKIiAiIgIiICIiAiIgIiqTjP5R9g4S1dLYqalqcszu4DVuxW0DtKqYkdHSa32UfrL3eoEgHRQWLlOV2fCLDWXu/3KmtFppGc89XVyBkbB+k+snoAOpJAHVc6PzTiF5WEhpcHfW8OeFb3Fs2WzxmO6XdnrFFGesUZ/0ruvUEdQ5i2OK+TtkPFW/UmZcdqynvNXA4TW3CKN27Raz6jIN6qJfUS7bfEekNa6OYxsTGsY0MY0aa1o0APYEEW4ZcMMd4Q4jTY3jFF3K2wudI7neZJJpXfXlkeernuPif0AaAAUrREES4h8KsX4q0trgye1suTbXXRXGjcXuY+GaNwIcHNIOjrRHgR/QtA7Nsnwi+53dc/8xWrhxbooqu13mCd/bNjI5ZI5oyDtwcNgt8e0a1vMfq2Ysevt9LdaGooq2mhrKOoYYpqeojD45GEaLXNPQgjoQUHnZ7xQZBa6W5WysguFvqoxNBVU0gkjlYRsOa4dCD7QsxQKXBr/AGfLcSfi19pLHhFqpX0NZi4tzDFLHy/enxSAh0bmkMbrq3l30345vDLipZOLFquFbZWV8Hm+ult1XTXKikpZ4J49ba5jwPUWu/Q4b0dgBMEREBERAREQEREBERAUfzzPbDwyxWvyPJblDarPRM55aiY/8GtA6ucT0DRsk9AtdxX4tY3wXw+pyPJ63utHGezihjHNPVSn6sMTPF73a6D1dSSACRTeA8J8l465VQcSOMFF3KhpH9vjeBSHmhtw/FqKsHpJUEddEeh7AfRaGix3hRXeVvm1u4kcSMejs2D288+N4tUwNFXWs8RU1ztb5T0LYd8vt2NmTrCONkMbY42tYxoDWtaNAAeAAX0iAiIgIiICIiAiIgozjPg9fkvG7hheGW6OtstoguYr5JXRlsRlia2L0HHbtuafqg6110tTxYwm4364cNjZaBklLZsohuNW2NzI2wU7aeoY54BI36UjRpuz18PFX/VW2mrJA+aPncBoHmI6f0FePmGh/wBB/bd80HK0XAi45Ng2eWq4g2O81WU3G82K5MkY90BkP3qX0SfRe0ua5h6lrnAgbX5w64bZXh+S4JcJrSyQWThx5jnHeow3v7ZKZwh2CTo9k/0wC0a8fBdVeYaH/Qf23fNQzhjkbOIVLkUtXi9bjptV7qrTGytc/dXHCWhtSzYb6D+bprY6eJQc7uwPMs4za6ZTPgtNgczscr7ZVQsuUFRNeZ5mtEIeYtN5Yy0kPeQ709aA8M7I+Dt1q/JdxrGKOwU5y2korHHPA10LXtkgmpXVH33YadCOTqHHeum9jfVvmGh/0H9t3zTzDQ/6D+275oMi3/5BTf8AhN/6BZC+Y42xRtY0aa0AAewL6QEREBERAREQFq8nvdlx2w1lfkVfQWyysaGVNTdJmRUzWvIYA9zyGgOLg3R8S4D1raLn7yzfJmj8pDhsyGhc2HLLKZKm0Svdpjy4N7SB3qAkDGdfU5rTvWwQjnD3y6eG1vxugoM0vlmsGQmWWKO247FLcabsRM9kJY+mbK1pc1oPISHDYPKA5u+pF/FXyQOF1Vl/lTYnYLlRSwG03B1bcIJmFph7ruQskaeo29jWEH1u0v7VICIsO8Xigx61VVzulZBb7dSRumnqqmQRxxMA2XOcegAQZi5tzvjrknFnKazh5wRdDPV0zuyvmcys7Sgs49bIj4TT+wDYB/8AMWaesyPLvLKqp7bitRXYXwYa8xVmRhpiuGQNB06KlDhuOE9QZCNnw19Zi6LwXA7Bw0xeix3GbXBaLPRt5YqaAdN+tziernHxLiSSepKCMcFeBON8D7HPTWls1fd65/b3S/XB3a1txmOyXyyHrrZOm+A2fEkk2MiICIiAiIgLTXfDrJfb1abxX2qjq7vaHPfb62eEOlpXPaWuLHeI2D1G/Z6wFuUQVNj/ABBufCrHrfTcZsmsMN2uV5kttruNDG+CGrY4F0PaNIIifoOB68o00cxJ2bFv+U2XFIaSW93egs8VXUMo6d9fUsgbNO7ZZEwvI5nnlOmjqdHp0XzlFLY57LPNkUVA+0UWq6aS5tYYIOxPaCZxf6LeQt5uY/V5d7Gl/FzynPKYv/lEZ5JX1FXMzG7bWVD7BRSwxRS0kMhZ9Z0Y2XuEUZO3O0QdH1kP7coqh8lHjIzjnwOx7I5ZhLdo4+43QbGxVxAB7iB4c45ZAPUJAreQEREBERAXlU1MNFTS1FRKyCniYZJJZXBrWNA2SSegAHrUK4tcacU4LWKO45LXmOWod2VFbaVna1ldL0AjgiHV7iSB6gNjZCqGl4YZz5TVTFdOKrZ8QwDmEtHw/opy2erAO2vuMzdH2HsW6103otOwyL5xvyvjvcazGeCDI4bVE91PceItfETQ0x8HMomH/KJR/G+oOnqcHCwuC/k94vwTpame3Nnu+SXDb7nkl1f21fXPJ24vkPUN3+KOnQb2epsKz2egx+10tttdHBbrfSxiKClpYxHFEweDWtHQD7AsxAREQEREBERAUO4ocPJOI+Ox26lyO8YnWQVcVbBcrJOIpmyM3oOBBa9hB0WOBB6exTFEEFtvEG6u4mXzF7lidxt1loKCOupcrmkjNFWN0BIwkEdm9rieh8Q1xIaOXml9ddqG2WuoudZWU9JbaeF1TNWTytZDFE1vM6RzydBoaCS4nQA2vLILDb8psVws11pm1lsuED6Wqp3kgSxPaWuaSCD1BI6L+cnlx8baXg5i9D5PfDerrLdbKCl7O+SvfI+XsZQJI6QSvOy1zJOZ/L0LXMZvXaMQf0koa6mudFT1lHURVdJURtmhqIHh8crHDbXNcOhBBBBHQgr3XEv+DM4+jMsBquHN3qzJeceaZrf2jtuloXEDlHrPZPOvsa9gH1V20gIiICIiAq9408bsf4H41HcbuZa241kndrXZaJvPWXKoOg2KJg6nqRt3gNj1kA67jnx8tnBugoqOGjmyPM7u7sbLjND6VTWy+AJA3yRg/WeegAOtnoo3wU4CXSiyWTiXxQq4ch4m1rOWJrOtHY4DvVNSt6gEAkOf4nZ0TtznhgcKuCN/zPMabinxhEVVlTBzWTGY3c9Fj0Z6gAeElR4F0nqI6eDSOhkRAREQEREBERAREQEREBERBHcu4j4nw/7p9KMos2N975+7+d7hDS9ty65+TtHDm1zN3rw5h7VVXDDyg8cpqbIRm3Fvh/WzyXuqfaTRX+jAjtxLe7sfpzfTA5t+J8OpWp8u/gV92rgbXS0MHa5FjvPdLfyt2+VrW/foR036bBsAeLmMXAXkCcCjxj44UldX03a45jPJca7mHoySgnsIT/rPHMQehbG8IP7FIiICIiAiIgLW37IKLG6EVNbIWh7xHFEwc0k0hBIYxvi46BP2AEnQBI2SqWK5HKbnNfZCJIn80NvHqjptjqPtkLQ8n1jkHXlCkppjKa6t0eslmxZ01eXY2NVmGT3NxdSsorHAR6LJ4zVT+P4xDmsadeoc36Viec8s944/h8fzUez7iVjvDC3UddkdbJRU9ZUijp+xpJql8kxa5wYGRMc76rHHw10XphHETHOI9vmrMcukVyhgk7Gdoa6OWF/8WSN4D2H7HAJp6o3RER8In75y7MYexE9HLa3vnPLPeOP4fH80855Z7xx/D4/mvZanLMrteD47XX29VJo7VRM7SoqBE+Ts27A3ysBcRsjeh08fAJrFfCPlp5Npw9mNs0wjNp4VRWLihduIdDVU9Nll0pBRVVayiaBJGC0k8nNy8zuRm3a2eQe07m3nPLPeOP4fH81h1OSWyjvFttU1ZGy4XKOWWkgO9zNjDTIWnw6B7f8AivKxZdaclrrzR22r71PaKruVaBG9rYpuRr+TmIAcQ17SeUnW9HqmsV8I+WnkaCz3YbHznlnvHH8Pj+agvFDhXPxjZa6fKshqLhaqCbvHmlkIipKl40WmdjSO0DSOgcdePTqVKH5hZ4r3cLRLXMhrrfRsuFUyVrmMigcXgSF5HLrcb99djWzpbG33Cmu1BTV1HOypo6mJs0M8R22RjgC1wPrBBBTWK+EfLTyNXsz/AAw86OpyW3UsNNS3umgp4GNjigjtkbY42gaDQ1pGgANADS2lDnV+tTh52o6e70uwHT2xhimYPaYnucHAevlcD7Gk9FjImnqn80RMfCI+2UsVYW1VGWSxbdcaa70MNZRzNqKaZvMyRngR/wCx9RB6g9FkqscduJxvKaaNpDLdd5DFLH6m1PLtkg9Q5g0sPtJZ9u7OSumIymndLh3rU2a+jIiIo0AiIgLCu93pLFb5a2um7Gnj1twaXOJJ0GtaAS5xJADQCSSAAs1VZcbkcoyOrrHkOorfNJR0TOuuZp5JpSPDmLw5gPqa06I53BSU0xMTVVuj1knsWpvV9FmVma5FdHk0FNSWWl68rq1hqJ3D1Eta5rWfo5ndPYT0ojL/ACQ8AzeQy19gs1LKTvmtVv7gN+s6hewH+nat3IMmteK0kFVdqyOhp56mKkjll3ymWRwZG0keG3EDZ6dV81+VWu2ZDabHU1XZXW6snko6fs3HtWwhplPMByt0Ht8SN76b6pp6o/LER+kT985duMNZpjLJA+CnA1nk/wBLd6XD7/VU1Hc5WTTU1VEJ2Me0EAsDj0JB0fbyt9isvznlnvHH8Pj+a9lh2u9UF8hmlt9ZBWxQzSU0j6eQPa2Vji17CR62uBBHqIITWK+EfLTyb6vZ7r2855Z7xx/D4/mnnPLPeOP4fH81iZFkNDilkq7tcnyxUNKznlfDBJO8DYHRkbXOd4+ABVdWzyo+HF4ugt1Hd7hNW9qyF0PmG4Ase/XKH7g03ewdu0NdfBNYr4R8tPJpNmxTOUxC0POeWe8cfw+P5p5zyz3jj+Hx/NeF8vVFjdkuF3uU3drdQU8lXUzcrndnExpc92mgk6AJ0AT7F626vgutvpq2lk7WlqYmzRSaI5mOALTo9RsEeKaxXwj5aeTbV7O7owr6wcGm2PiFW5zLeZb1ltTtrbpd6dtTJTR9fvcAceWFvUjTAOhI3oqy6bKsrtzg6WW3XmIfWiMLqWU/oeHObv7C0fpC+UTWKp3xHhH7REk4azP8KbY5k9Jk1PI+BslPUwkNno6gASwk+HMASCD105pIOjonRW4VRXGeWzSMvlG3/HKEczgPGaDYMkR9vM0HXscGn1K2KWqiraWGogeJIJmCSN7fBzSNg/8ABZqiJpiundPlPrc4uIsaGrKN0vVERRKoiIgL8JABJOgF+qAcQ7kbnc4Mbaf8VMIq7g3r6cZcWxRH817mPLh6xHynYcVvRT0p27o3+vW1Jbom5VFMP25cRKu4uLMcpoJaf1XOu5uxf9scbdOkb+cS0HoWlwO1q33bLJHE+f6ePr4R25uv63E/1r0Vfw8e8DqssGN09/bVXY1QouWnpZ5YRPvXZmZrDGHb6aLuhWdPMbKKYiPhE/f/AB8HcjDWbcRFXmnXnPLPeOP4fH81SueeSJgvEi/Vl7vlroX3askdLUVVHA+kMsjjtz3Nika1zidkuIJJJJ2SVbeP5Va8oNzFsqu8m21sluq/vb2dnUMAL2ekBvXM3qNjr0K2qaxXwj5aeSSMPZndTCgeGvkdY3wjzyhy7F7rX2+60YkbG0kviIexzHBzXOPMNOJ0TrYHsV8ec8s944/h8fzXssK3Xu33htW6hrYKttJO+lndDIHCKVn12OI8HNPQj1HoU1ivhHy08mdXs917+c8s944/h8fzTznlnvHH8Pj+agFr8ofh5e8kgsVBksNXcKic0sLoqeZ1PLKPxGT8nZOd0PQOViprFfCPlp5NYsWKt0Q8fOeWe8cfw+P5p5zyz3jj+Hx/NeyJrFfCPlp5NtXtd1XmLcJHYpn98zeG9yXDK7ueWa6XGmbPLFF6oYdnUUY6DlaB0AB3oKe+c8s944/h8fzXsiaxXwj5aeRq9ruvHznlnvHH8Pj+aec8s944/h8fzXj56oDeTaRWQG6CnFUaMPHaiEu5RIW+IaXAgH1kH2FZiaxXwj5aeRq9nuvyLIMtpHBzbnb68DW4qmiMfMPXp7H9D9vKf0KVYxmsV+mNFVUr7ZdWsLzTPdzskaOhdFIAA8Akb6Bw2NtGxuLLGuFF32FobIYKiJwlgqG/WhkH1Xj9Hs8CCQdgkLMXYr2XIj4xGWXhvQXcHbqj8EZStdFpcOv5ybHaWukY2KpPNFURM3ysmY4skaN9dczXaJ8Ro+tbpaVUzRVNM74cKYmJykREWrAiIggmeXy80mSWi22uvZQRz0lTUSvdTtlLix8LWgb8P4Ry1Pf8r95I/h8fzWbnf4fWH/dlb+9pV5qti8TcsTRTbyyy4RPbPGHlvaWMv2L/AELdWUZRwY3f8r95I/h8fzTv+V+8kfw+P5rJRUesMRxj5aeTl9ZYvv8AlHJjd/yv3kj+Hx/NQjhdwobwapbxT4ncIrbFdq+S4VQFCx25Hfit2fRY0dGtHQbPtKsBE6wxHGPlp5HWWL7/AJRyY3f8r95I/h8fzTv+V+8kfw+P5rCu2VWuxXazWyuquwrrxM+noYuze7tpGRulcNgEN0xjjtxA6a8ei2ya/iOMfLTyZn2ji431+UcmN3/K/eSP4fH81r8hyTLbHYq+4NyCKZ1LA+YRuoGAO5RvRO1uVoM+/Am+/wCxS/8ApKsYbG3q71FNWWUzH8NPH4JLPtHFVXKaZr2TMdkclzoiK+9wwr12vmeu7H+G7CTk/wBblOv61VeLcv0YtHLvl7nDrfjrkCuFVLFbTi1ymsUgDImF01vPXUlPsdB9sZcGEeoch6cwU35rU0xvic/0dPA1xFU0z2qw48/hDwi/njB/+JVKseNOYVuHcV+Id5xOeOmrKPD6KnuVXG0ObT1Ute1kMkg8C+OB8jxv8UD1LoLP+GmOcULbR0OSUMldTUdSKyARVU1M6OYNc0OD4ntd9V7hreuq88e4U4jiuNV9gtlhpILTcA8VtO9pl71zDTu1c8l0hI6bcT0VV0q7dVUzl62KXzi9XngBkUsFlv15ymGrxS63OSkvla6tdDUUjY3RTgu6sa8vc1zRpp10A0pnhvCOG/YMKi65fkGSOyKyOhru+3Ey0c3eIhzSRwfUj1zHlDNaB678VLcO4OYfgU9XPZbM2GeqgFLLNU1EtU8wjwiDpnvLY/zBpv2LyxDgnheBXgXOw2Y0FU1r2RgVc74oWvILmxxOeWRg6HRjQsEW5z27vs5cst/vVypLXxJuQqY38JzRWGuiYCTM5rnw3R+vWRE+B/8A5CpVh9hvNXLwgpZ71dbE7M5L3kV7jtlW+nfUOmbHPGxxaQQWtdG3Y9JoB0Wk7HSrsHsTrNe7SbbF5vvT55LhACQKh0w5ZS473tw9ml91GG2aqvFjuklE3v1kjlit8jXuaIGSNax4DQQ07a1o6g6100s5tIszHb6z5bFE5DZZqLJOLuNee79V2mPC6Wpihq7vUTOjk1UtLmOc8lpcIWc2vrdd72Vp55rvhvBjhDYsYuFwMmXvo46mqrL3NG5gND2nYQ1D2ymnDyxoaI29OoaAXbHR7cPs7MiuF87k11zuFJHQ1Uz3ucJYIy8sYWE8ugZH+A2d9d9FF6XgHgdJi9ZjjLCH2SqkZK6jmqp5WxuYSWGIueTDy7OuzLdepM202p7PW1TmZWviXg3C/KhW3yotNNPcLPHaZYr7Lc6yje+tijnBqHwxOcxzXM013N4vBJB0ujcYxuLFrZ3KKtuNwBeZHT3Sskqpi4+PpvJIHsaNAeoBR+j4LYdQY1U2CK0vdbKqrhrp2S1s8kks8T2Pje6Vzy8kGKPxdrTQPDopssJKKJpnOfW9rMg5+xt3Zb7XzpQcnL7e9xf1a3v7Nq4VWWOW76SZRTSNAfbrRIZZZPU6p5dMjHqPKHFx9h5Pt1Zqt1fht00Tv2z45cs/1cfG1xVcyjsERFC54iIgKl8M5/o1RdpvttO7Tfjz8x5v69q6FVlxtpxfI6qjcA2iuM0lZRP6653HnmiJ8OYOLngetrjoHkcVNH4rVVMb9k+Gef3z+Do4GuKa5ie1UPlVWmlv/Da2Wytj7WircitNNPGHFvNG+sja4bHUbBPgq3uGT5BivF/E8fvEc10vuKWW+z0dfK06utKYITTSEj/OfenRyD+Mwu8HBdLZJitry+jp6S7Uve6enqoa2JnaPZyzRPEkbttIJ05oOj0OuoIXpW47bbjeLddamkjluNuEgpak754hI3leAfY4AbB6dAfEBVHVrtzVV0ong51sNXesbsXCDMBmN6vlyzCuo6a60VXWmSkmZVQPkf2MP1YeycAQWBvRpDt7Wixqap4R+T9xJyuw3C5SXemvdxoI+/3KaoggBuRi7cxyOcwPa13O55aSdEu3s7v7HOB2D4lkMd7tNgjpbhCZDTnt5XxUxk+v2MTnmOHm2d9m1vQkLIpuD2H0l6vd0isrBU3tkrLjE6aV1PUiTXaF0BcYtu5RzODdn1lZzaaKr190D4X4ZxEx3NaKqrqt5xqWllbXQ1+UTXl80mgYpYu0po+yIOwQ13KQ7o0aC1TclocQy/yjLxcqispKKl83Okmt2u8s3bY2gxb6B+yOUnpvW+itHB+D+JcOKuWqx+1vop5Ie788lZPUckWwezYJXuDG7A9Fuh0Czp+HGN1UuTyT2qOoOTNY27Nme97KoMiETQWkkN0wAeiB4b8eqNtHVER67HNFVVZZjkHErGb066QW2u4eXC7RUN4vpu88UrQ6Pm7RzG9nsPILGlzdtBBWRinFHJLXg2cZDXtr7Vf7BitNLYsdnk/xcUJgBZXOY13LLI6RrubY3GGBnTZJu+i8n3AreKkw2N5lqaGe2Tzy19TJNNSzNDZIXyOkLnM00aBPonq3lPVSGXh1jk1daayS2MfUWqikt1K4yP0KZ7WtfC8b1Kwhrejw7qN+PVM2kWq47VP8NMV4k0N+sF6kuTprDUU75Lm6ryqW6CsY+EmOSGJ1LG2FwfyO+9uDeUka8FvPJZtFbV8KsYyi75De79eLnbWmZ1xuEssIaXbbyxE8ocAAC/XMeuydqX4dwTwzAbk6vsVnNDUmJ9OzdXPKyKNxBcyNj3ubG0lo6MAHQKSYti9swvHrfYrNTdztVBEIKan7R0nIweA5nEuP9JKwkotzTMTPrc2h1o78FJ+GHafc5xntObm83Qa5vHl7Mcu/t1pQm4wS3mRljo3f45XNLXEeMMGwJJT7NAnXtcWj1q2KWlioqWGngYI4IWCONjfBrQNAf8Faj8NrKe2c/DPn5Odj64maaXqiIonKEREBVZc+f7oGRc+/qUvJ/qdmf/25laagHEO2m2XODI2Ad2EIpLg7r6EYcXRSn81jnvDj6hJzHQaVNb2xVRG+Y/eJ/ZbwtcUXYmUR4hOuDMByV1p5/OotlSaTs/rdt2TuTX282lE/JylssPAXBXWiSBtAbXTBzmEAGoLQJQ788yl4P5xKstV1H5PHDuHJfP0eMU7K/vQreVs0op+3B2Je78/Zc++vNyb31VR3pielFUKIulFccdw/jHndryS9W65WLLauemoqarLKJ/K6AuEsIGpOcOLTzb0ANa672fH3Kb8KzOchw6syGKTD2xCqq3X3u1uhnbGyQxMowxwqNtc3n5+Xq/QKv6r4V4vX4/kNjntfPa8gqZKy5wd4lHeJX8vO7mDuZu+RvRpA6dAtdk3ArBcwu9fc7xYI62puDBHVtdUTNhqNN5Wukia8Mc9o0A8t5m6GiNBZzQTaqyyifW3/AAhljt1dm/HzN463Ib3T2i00tmqaa10Vxlgg7V7JXOLgwglp5NFn1Xcx5gdDVYU2JVFj4Fcd7hZK+9T3KO53uhEU1zqJ2di2YF7+zc8t7Uxh25Nc52evVdQ4/g9lxe5VtwttI6GtrYKamqJnzySukjp2uZCDzuPVoc7r4neySVhW7hdjFoy24ZLRW0013uHMap8dRKIpnOADnOh5uzLiGjbuXZ14pm2m1M+fmhWS8Qqfhhwyw654jY7feMRkdRUjXNrOw7CGV8UUL42iNwedv2RtutePVV5cH8ReKuacQDZauejNiuj7Vb2w5PLbWUnJExzZZKZlNI2cPc4u3I4gj0QBy7NrUHk1cNLZeIrlTYpTxzQ1HeooDPM6lil3sPZTl5iaQeo0waWyyrgdhGa32S83extnuMzGxTyw1M0AqWN+q2Zsb2tlAHQB4d06eCE0V1b/AF5Ktbasky/OM5tt+yq826rs+N2qo7GxXKSnp466SKo7WVnLolvPH0adNcPrNOhqM0GbZ1xcuOFWanmmdzYZRX6pjpr/ACWWSrqJXFj5e1igkc5rS0egOUAydd9AOmIsMs0F6vF2ZR8twu9PDS103av++xRB4jbrem6Ej+rQCd9d6Cjl04E4NebLYbXU2P8AxaxQCmtr4KueGemiDQ3kEzHiQtIA2C47112mbE2quyfWap4rHnVRmvDLE8sym4UhmpL3JWGy3SQPq4I305p2yzNZGXSNa8AyNa1x07WuYrScbr9e7cMxu+F1+TbwiGCKprqrIXRUUczIo39mKYsf3oljml5lI2XnTl0XbeG+N2ersNTRWxtPNYqWajtxZLJqCKXk7RuubTt9mzq7Z6dD1O9Rk3ArBcwu9fc7xYI62puDBHVtdUTNhqNN5Wukia8Mc9o0A8t5m6GiNBMyq1VlMRPrJAzilLefK0fcJK67QSjFKO4Nip7nPFEXNq5G8hY14a6PTQTGRyklxI24kwmXIchHCOfi6/Kry3I2XwsbZBWHzeIhce69yNN9Ukxj62ufmO+ZX9d+EWKX2tslbW22SStssLaeiqmVk8czIwWkMe9rw6Ru2g6eXAnqepKxX8DsHflf0jdYIjde99/328vYd5/0/Yc/Zdp6+fk5t9d7WCbVW3L1/wDEQ4YWyvyTinxFuNxyG9T0tmyEU9BbG18jKWIdzhc7cYOntJfsMdtoI2ACSTdK1VkxW147WXert1L3eou9V32tf2j3drNyMj5tOJDfRjYNN0OnhslZlwre5QtLYzPUSuEUFO3600h+qwfp9vgACToAlbU0zXMUxvTUx0KdrfcKefueQb32XnaTs9+zsoub+1zKcrS4dj5xnHaSgke2WpHNLUSs3yvme4vkcN9dcznaB8BoepbpWbsxVXOW7lseauVRVXNUCIihRiIiCu87/D6w/wC7K397SrzXpnf4fWH/AHZW/vaVRvK6XKqnuv0audnt3Lzd487W6Wr5/Dl5Ozni5delvfNvY8NdeZj9tdH/AF/eXi/a0Z4rLPshIFVXlI5fesRwCj8xSilrbrd6K0msMwg7vHNKGuf2pY8Rkj0Q8tdyl/No6W2818UtfhLiG/b9Hqr/APuWRFh98ye23K0Z9UY7kdirIeydRUVpmpuY7B24yVEoIGtjQBBAIPRc6nKmYmdrl0RRRVFVUxMR2beSjcytXE7htw24h3OoulRbrRHYXSUrXZLPdqyCtbI3Ukc0kET2MLC4FuyNgaA2Vvsrvd54K5lc3W+83fIIJsKud6fSXmsfUtNZSuiLJGA/wYcJHBzGcrfDTRpWZQcB8Ht2OXuxRWeR9tvULaevZPX1M0k8bd8rO1fIXtaOZ2g1w1s6UlrMOs9fkNLfKmibNc6ajloIpnvcQIJSx0jCzfKQTGzqQT0+0qSbkcFmcRRO+M429m/ZGXbPa55t+Iz23NeA9/q8sveTV13qaipqZK+tMtK58lsnfzwxfVib1IAZocp67PVdQKsbb5PGF4tV090xqzRW2928zS2uaoqaqeno5ZI3sJEHbBvIQ87Y3lB9WiARsGWziiHtL8kxFzN+kG49VAkfYe/HS1rmK8spRXq6b0xMVbuMZdsz2Z8U+Wgz78Cb7/sUv/pK0DLZxRD28+S4iWb6huPVQOv25b/PvwJvv+xS/wDpKmwsZYi3t/ij7tbNMReoynPbH3XOiIu4+jC1t+x+iyOiFNWxlwY8SxSsPLJDIAQHsd4tOiR9oJB2CQdkizEzTOcMxMxOcK2qsPya2OLaV9Fe4APRfPIaWfx/G5WOY469Y5f0LE82ZX7uR/EI/krURS6Smd9ET4x9piFyMZdiMs1V+bMr93I/iEfyTzZlfu5H8Qj+StRFnp0e7j6ubOu3VV+bMr93I/iEfyTzZlfu5H8Qj+StRE6dHu4+rma7dVX5syv3cj+IR/JPNmV+7kfxCP5K1ETp0e7j6uZrt1VgteVu6DHomn1F1wZr+oFZ1Dgt+urh52rKe00u9ugtjzLM8ewyva0NB9fKwn2OB6qxUTSUxtpoiJ/WfvMw1qxd2qMs2NbrdTWmhho6OFtPTQt5WRs8AP8A3PrJ8SVkoihmZmc5UxERYBERAWHd7RSX23y0VdD21PJrbQ4tIIOw5rmkFrgQCHAgggEEFZiLMTMTnBuVxWYVkVreRb6mkvNL15W1rzTztHqBe1rmv/Tyt6e0+OGbXlYOvo7GftFwZr/orTRS6SmfzURPjH2mIXacXdpjLNVfmzK/dyP4hH8k82ZX7uR/EI/krURZ6dHu4+rmzrt1VfmzK/dyP4hH8k82ZX7uR/EI/krUROnR7uPq5mu3VV+bMr93I/iEfyTzZlfu5H8Qj+StRE6dHu4+rma7dVYLZle/wcj+IR/Je9NiuV3FwbLFbrNCfGUzOqpR+hga1u/tLj+gqzEWNJTG6iPP95mGJxl2e1qMcxikxqnkZA6SoqJiHT1lQQZZiPAuIAAA66a0Bo2dAbK26Io6qpqnOVOZmZzkREWrAiIgL8IBBBGwV+oggNy4dVducX45UwRU/qtlbzdiz7I5G7dG383TmjoGhoGlq32nK43EGwU8nX60VwaR/aaD/UrSRT6SJ210xM/r+0wt0Yq7RGUSqvzZlfu5H8Qj+SebMr93I/iEfyVqInTo93H1c2+u3VV+bMr93I/iEfyTzZlfu5H8Qj+StRE6dHu4+rma7dVX5syv3cj+IR/JPNmV+7kfxCP5K1ETp0e7j6uZrt1VfmzK/dyP4hH8k82ZX7uR/EI/krUROnR7uPq5mu3VV+bMr93I/iEfyTzZlfu5H8Qj+StRE6dHu4+rma7dVX5syv3cj+IR/JPNmV+7kfxCP5K1ETp0e7j6uZrt1WEWPZbWENbbbfQA63LU1pkLR69MYzqfs5h+lSvGMKisMxraqpfc7q5hYap7eRkbT1LYowSGNJA31LjobcdDUkRYm5sypiI+H+c5RXMRcuRlVOwREUKsIiICIiCCZ5Y7xV5JaLla6BlfHBSVNPKx1Q2ItL3wuaRvx/g3LU9wyv3cZ8Qj+StFErpt3MtJREzGzt/aYUb2CsYirp3Kc5+Mqu7hlfu4z4hH8k7hlfu4z4hH8laKLTQ4f3UeNX9yDqvCdzznmq7uGV+7jPiEfyTuGV+7jPiEfyVoomhw/uo8av7jqvCdzznmq7uGV+7jPiEfyTuGV+7jPiEfyVoomhw/uo8av7jqvCdzznmq7uGV+7jPiEfyWvyHG8tvlir7eywRQuqoHwiR1ewhvMNbPRXCi3oos26orptxnG3fV/c2p9m4WiqKop2x/OeYiIjpv//Z",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from IPython.display import Image, display\n",
    "\n",
    "display(Image(chain.get_graph().draw_mermaid_png()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "9860fd46-c24d-40a5-a6ba-e8fddcd43369",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-15T08:19:53.723467Z",
     "start_time": "2024-05-15T08:19:53.709307Z"
    }
   },
   "outputs": [],
   "source": [
    "for s in authoring_chain.stream(\n",
    "    \"Write an outline for poem and then write the poem to disk.\",\n",
    "    {\"recursion_limit\": 100},\n",
    "):\n",
    "    if \"__end__\" not in s:\n",
    "        print(s)\n",
    "        print(\"---\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f4b5b08d-9a9a-474a-94b4-f7aaa8ff19e6",
   "metadata": {},
   "source": [
    "## Add Layers\n",
    "\n",
    "In this design, we are enforcing a top-down planning policy. We've created two graphs already, but we have to decide how to route work between the two.\n",
    "\n",
    "We'll create a _third_ graph to orchestrate the previous two, and add some connectors to define how this top-level state is shared between the different graphs."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "95ae7e52-92ed-41a3-88c4-21b6d7c8b041",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-15T08:19:55.454047Z",
     "start_time": "2024-05-15T08:19:53.725466Z"
    }
   },
   "outputs": [],
   "source": [
    "from langchain_core.messages import BaseMessage\n",
    "from langchain_openai.chat_models import ChatOpenAI\n",
    "\n",
    "llm = ChatOpenAI(model=\"gpt-4-1106-preview\")\n",
    "\n",
    "supervisor_node = create_team_supervisor(\n",
    "    llm,\n",
    "    \"You are a supervisor tasked with managing a conversation between the\"\n",
    "    \" following teams: {team_members}. Given the following user request,\"\n",
    "    \" respond with the worker to act next. Each worker will perform a\"\n",
    "    \" task and respond with their results and status. When finished,\"\n",
    "    \" respond with FINISH.\",\n",
    "    [\"ResearchTeam\", \"PaperWritingTeam\"],\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "4880e573-612f-4d24-97c1-2079382a4a2f",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-15T08:19:55.469348Z",
     "start_time": "2024-05-15T08:19:55.455831Z"
    }
   },
   "outputs": [],
   "source": [
    "# Top-level graph state\n",
    "class State(TypedDict):\n",
    "    messages: Annotated[List[BaseMessage], operator.add]\n",
    "    next: str\n",
    "\n",
    "\n",
    "def get_last_message(state: State) -> str:\n",
    "    return state[\"messages\"][-1].content\n",
    "\n",
    "\n",
    "def join_graph(response: dict):\n",
    "    return {\"messages\": [response[\"messages\"][-1]]}\n",
    "\n",
    "\n",
    "# Define the graph.\n",
    "super_graph = StateGraph(State)\n",
    "# First add the nodes, which will do the work\n",
    "super_graph.add_node(\"ResearchTeam\", get_last_message | research_chain | join_graph)\n",
    "super_graph.add_node(\n",
    "    \"PaperWritingTeam\", get_last_message | authoring_chain | join_graph\n",
    ")\n",
    "super_graph.add_node(\"supervisor\", supervisor_node)\n",
    "\n",
    "# Define the graph connections, which controls how the logic\n",
    "# propagates through the program\n",
    "super_graph.add_edge(\"ResearchTeam\", \"supervisor\")\n",
    "super_graph.add_edge(\"PaperWritingTeam\", \"supervisor\")\n",
    "super_graph.add_conditional_edges(\n",
    "    \"supervisor\",\n",
    "    lambda x: x[\"next\"],\n",
    "    {\n",
    "        \"PaperWritingTeam\": \"PaperWritingTeam\",\n",
    "        \"ResearchTeam\": \"ResearchTeam\",\n",
    "        \"FINISH\": END,\n",
    "    },\n",
    ")\n",
    "super_graph.set_entry_point(\"supervisor\")\n",
    "super_graph = super_graph.compile()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "270ff3ae26cd42ff",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-15T08:32:33.694459Z",
     "start_time": "2024-05-15T08:32:31.524790Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/jpeg": "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a3Q3CIi1l7Pw7/XdlH8DRf1ysFV9w7/XdlH8DRf1ysFe9t/wrf8AbT/jDy2VfxqhERZtUREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERBTWD/rTtn8F/7laCo4DcN6qeSabA8dlmkcXvkfbIS5zidkk8vUkqy4OENrpImxU9zvEELd8sbKzTWj2Dov7/AAVUP2xe/wBN/sXLvezpuXq7tF3DOmZ2T0y7sZbZwiJhV7+APDSR7nvwHHHPcdlzrZCST7fqqaWy2Ullt1NQUFNFRUVNG2KCngYGRxsA0GtaOgAHqC3n4KqH7Yvf6b/Yn4KqH7Yvf6b/AGLXn2VVVtvR3SmMusxspa1FsvwVUP2xe/03+xVF5OtLW8Svwnd9Xu6P7gzi52Gi7Go5NUsHZdmHdPSd6Z2fWseZ/wDtjullzha3SstRfJ+FuHZrcGV2QYvaL1WsjELaivoo5ntYCSGhzgTrbnHX3lTr8FVD9sXv9N/sT8FVD9sXv9N/sUx7JmmcYux3SicvtTqmJVd/e/8ADPWvoBjevZ3XD/8AqpLi+F2DCKOWkx6y0FkpZZO1khoKdsLHv0BzENA2dADf3KWfgqofti9/pv8AYn4KqH7Yvf6b/Ysp9lV1RhN76sYy2zGuKXk4d/ruyj+Bov65WCtBjGGUWKTVs1NPV1M1XyCWSrm7R2mb5QOnT6xW/XbimKKaaInHCIjuiIci9XFy5NcdIiIikREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBc7+Rv/lx/wBqV8/qF0Qud/I3/wAuP+1K+f1CDohERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBc7+Rv/lx/2pXz+oXRC538jf8Ay4/7Ur5/UIOiEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQERfCdDZ8EH1FB6/iYJ5DHYbebswHRrZZexpT97H6cZB97Wlp9TvZrTmmWuOxSWVn70yTO1/Hof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",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from IPython.display import Image, display\n",
    "\n",
    "display(Image(super_graph.get_graph().draw_mermaid_png()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6b8badbf-d728-44bd-a2a7-5b4e587c92fe",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-15T08:19:55.796497Z",
     "start_time": "2024-05-15T08:19:55.796497Z"
    }
   },
   "outputs": [],
   "source": [
    "for s in super_graph.stream(\n",
    "    {\n",
    "        \"messages\": [\n",
    "            HumanMessage(\n",
    "                content=\"Write a brief research report on the North American sturgeon. Include a chart.\"\n",
    "            )\n",
    "        ],\n",
    "    },\n",
    "    {\"recursion_limit\": 150},\n",
    "):\n",
    "    if \"__end__\" not in s:\n",
    "        print(s)\n",
    "        print(\"---\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
